﻿using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Ionic.Zip;

namespace GingerGL.IO
{
    //----------------------------------------------------------------//
    /// <summary>
    /// Zip File System Class
    /// </summary>
    public class ZipFileSystem : IFileSystem
    {
        //------------------------------------------------------------//
        #region Variables
        private ZipFile mZipFile;
        private ICollection<string> mCache;
        #endregion
        //------------------------------------------------------------//
        #region Properties

        #endregion
        //------------------------------------------------------------//
        #region Constructors
        /// <summary>
        /// Initailizes a new instance of object
        /// </summary>
        public ZipFileSystem(string zipfile)
        {
            //do you exist?
            if (!File.Exists(zipfile)) { throw new FileNotFoundException(zipfile); }
            //open the file.
            this.mZipFile = ZipFile.Read(zipfile);
            this.mCache = this.mZipFile.EntryFileNames;
        }
        #endregion
        //------------------------------------------------------------//
        #region Methods
        /// <summary>
        /// Opens a File Streams
        /// </summary>
        public Stream Open(string filename)
        {
            if (this.mCache.Contains(filename))
                return mZipFile[filename].OpenReader();
            throw new FileNotFoundException("File not found.");
        }
        /// <summary>
        /// Returns TRUE if file exists
        /// </summary>
        public bool Exists(string filename) { return this.mCache.Contains(filename); }
        /// <summary>
        /// Gets Full Path of File
        /// </summary>
        public string GetFullPath(string filename) { if (this.Exists(filename)) return filename; else return null; }
        /// <summary>
        /// Gets a list of files
        /// </summary>
        public string[] GetFiles(string path)
        {
            List<string> files = new List<string>();
            foreach (string part in mCache)
                if(!this.mZipFile[part].IsDirectory)
                    if(part.StartsWith(path))
                        files.Add(part);
            return files.ToArray();
        }
        /// <summary>
        /// Gets a list of files
        /// </summary>
        public string[] GetFiles(string path, string pattern)
        {
            return Path.Match(GetFiles(path), pattern);
        }
        /// <summary>
        /// Gets a list of directories
        /// </summary>
        public string[] GetDirectories(string path)
        {
            List<string> dirs = new List<string>();
            foreach (string part in mCache)
                if(mZipFile[part].IsDirectory)
                    if (part.StartsWith(path))
                        if(!dirs.Contains(part))
                            dirs.Add(part);
            return dirs.ToArray();
        }
        /// <summary>
        /// Gets a list of directories
        /// </summary>
        public string[] GetDirectories(string path, string pattern)
        {
            return Path.Match(GetDirectories(path), path + "/" + pattern);
        }
        #endregion
        //------------------------------------------------------------//
    }
    //----------------------------------------------------------------//
}
